#ifndef THINK_THINK_CONSOLE_OUTPUT_DESCRIPTOR_CONSOLE_H
#define THINK_THINK_CONSOLE_OUTPUT_DESCRIPTOR_CONSOLE_H

static char* think_console_output_descriptor_console =
	"\n"
	"// +----------------------------------------------------------------------\n"
	"// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n"
	"// +----------------------------------------------------------------------\n"
	"// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n"
	"// +----------------------------------------------------------------------\n"
	"// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n"
	"// +----------------------------------------------------------------------\n"
	"// | Author: yunwuxin <448901948@qq.com>\n"
	"// +----------------------------------------------------------------------\n"
	"\n"
	"namespace think\\console\\output\\descriptor;\n"
	"\n"
	"use think\\Console as ThinkConsole;\n"
	"use think\\console\\Command;\n"
	"\n"
	"class Console\n"
	"{\n"
	"\n"
	"    const GLOBAL_NAMESPACE = \'_global\';\n"
	"\n"
	"    /**\n"
	"     * @var ThinkConsole\n"
	"     */\n"
	"    private $console;\n"
	"\n"
	"    /**\n"
	"     * @var null|string\n"
	"     */\n"
	"    private $namespace;\n"
	"\n"
	"    /**\n"
	"     * @var array\n"
	"     */\n"
	"    private $namespaces;\n"
	"\n"
	"    /**\n"
	"     * @var Command[]\n"
	"     */\n"
	"    private $commands;\n"
	"\n"
	"    /**\n"
	"     * @var Command[]\n"
	"     */\n"
	"    private $aliases;\n"
	"\n"
	"    /**\n"
	"     * 构造方法\n"
	"     * @param ThinkConsole $console\n"
	"     * @param string|null  $namespace\n"
	"     */\n"
	"    public function __construct(ThinkConsole $console, $namespace = null)\n"
	"    {\n"
	"        $this->console   = $console;\n"
	"        $this->namespace = $namespace;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * @return array\n"
	"     */\n"
	"    public function getNamespaces()\n"
	"    {\n"
	"        if (null === $this->namespaces) {\n"
	"            $this->inspectConsole();\n"
	"        }\n"
	"\n"
	"        return $this->namespaces;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * @return Command[]\n"
	"     */\n"
	"    public function getCommands()\n"
	"    {\n"
	"        if (null === $this->commands) {\n"
	"            $this->inspectConsole();\n"
	"        }\n"
	"\n"
	"        return $this->commands;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * @param string $name\n"
	"     * @return Command\n"
	"     * @throws \\InvalidArgumentException\n"
	"     */\n"
	"    public function getCommand($name)\n"
	"    {\n"
	"        if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {\n"
	"            throw new \\InvalidArgumentException(sprintf(\'Command %s does not exist.\', $name));\n"
	"        }\n"
	"\n"
	"        return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];\n"
	"    }\n"
	"\n"
	"    private function inspectConsole()\n"
	"    {\n"
	"        $this->commands   = [];\n"
	"        $this->namespaces = [];\n"
	"\n"
	"        $all = $this->console->all($this->namespace ? $this->console->findNamespace($this->namespace) : null);\n"
	"        foreach ($this->sortCommands($all) as $namespace => $commands) {\n"
	"            $names = [];\n"
	"\n"
	"            /** @var Command $command */\n"
	"            foreach ($commands as $name => $command) {\n"
	"                if (!$command->getName()) {\n"
	"                    continue;\n"
	"                }\n"
	"\n"
	"                if ($command->getName() === $name) {\n"
	"                    $this->commands[$name] = $command;\n"
	"                } else {\n"
	"                    $this->aliases[$name] = $command;\n"
	"                }\n"
	"\n"
	"                $names[] = $name;\n"
	"            }\n"
	"\n"
	"            $this->namespaces[$namespace] = [\'id\' => $namespace, \'commands\' => $names];\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * @param array $commands\n"
	"     * @return array\n"
	"     */\n"
	"    private function sortCommands(array $commands)\n"
	"    {\n"
	"        $namespacedCommands = [];\n"
	"        foreach ($commands as $name => $command) {\n"
	"            $key = $this->console->extractNamespace($name, 1);\n"
	"            if (!$key) {\n"
	"                $key = self::GLOBAL_NAMESPACE;\n"
	"            }\n"
	"\n"
	"            $namespacedCommands[$key][$name] = $command;\n"
	"        }\n"
	"        ksort($namespacedCommands);\n"
	"\n"
	"        foreach ($namespacedCommands as &$commandsSet) {\n"
	"            ksort($commandsSet);\n"
	"        }\n"
	"        // unset reference to keep scope clear\n"
	"        unset($commandsSet);\n"
	"\n"
	"        return $namespacedCommands;\n"
	"    }\n"
	"}\n"
	"\n"
;
#endif